/* Turska Framework/UI library (Turs2)
 * Copyright 2003-2009 Jetro Lauha
 * All rights reserved.
 * Web: http://iki.fi/jetro/turska/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of EITHER:
 *   (1) The GNU Lesser General Public License as published by the Free
 *       Software Foundation; either version 2.1 of the License, or (at
 *       your option) any later version. The text of the GNU Lesser
 *       General Public License is included with this library in the
 *       file LICENSE-LGPL.txt.
 *   (2) The BSD-style license that is included with this library in
 *       the file LICENSE-BSD.txt.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
 * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details.
 *
 * Original version of this file contributed by Mikko Lehtonen.
 *
 * $Id: T2BMFont.h 131 2009-06-05 05:58:05Z jlauha $
 * $Revision: 131 $
 */

#ifndef T2BMFONT_H_INCLUDED
#define T2BMFONT_H_INCLUDED


namespace turska
{
    //! Bitmap font class supporting AngelCode BMFont tool. 
    /*!
     * Current limitations:
     * - Only the text format font descriptor is supported
     * - Unicode support is lacking.
     *
     * Recommended font export options for BMFont:
     * - Both horizontal and vertical spacing at least 1
     * - Padding as you like
     * - Width & Height: performance is better if font fits in a single page,
     *                   so use big enough width & height for that if you can
     * - Bit depth 32
     * - Don't enabled "Pack chars in multiple channels" (not supported)
     * - A: outline
     * - R, G and B: "one" if your outline thickness is 0, or "glyph" otherwise
     * - Font descriptor: Text (only Text is supported currently)
     * - Textures: png
     */
    class BMFont : public Font
    {
    public:
        //! Defines BMFont related constants.
        enum BMF_CONSTANTS
        {
            MAX_FIELD_LENGTH = 64,
            MAX_FILENAME_LENGTH = 128,
            PADDING_UP = 0,
            PADDING_RIGHT,
            PADDING_DOWN,
            PADDING_LEFT
        };

        struct Info
        {
            C8 face[MAX_FIELD_LENGTH];
            C8 charset[MAX_FIELD_LENGTH];
            UI16 size;
            I16 stretchH;
            I16 padding[4];
            I16 horizSpacing;
            I16 vertSpacing;
            I16 outline;
            I8 aa;
            bool bold;
            bool italic;
            bool unicode;
            bool smooth;
        };

        struct Common
        {
            UI16 lineHeight;
            I16 base;
            I16 scaleW;
            I16 scaleH;
            UI16 pages;        
            UI8 alphaChnl;
            UI8 redChnl;
            UI8 greenChnl;
            UI8 blueChnl;
            bool packed;
        };

        struct Page
        {
            Page();
            ~Page();
            UI16 id;
            C8 file[MAX_FILENAME_LENGTH];
            Image *fontImage;
        };

        struct Char
        {
            UI32 id;
            I16 firstKernIndex;
            UI16 x, y;
            UI16 width, height;
            I16 xoffset, yoffset;
            I16 xadvance;
            UI16 page;
            UI8 chnl;
        };

        struct Kerning
        {
            I32 first, second;
            I16 amount;
        };

        struct FontData
        {
            FontData();
            ~FontData();
            void reset();

            Info info;
            Common common;
            Page *pages;
            I32 kerningCount;
            Kerning *kernings;
            I32 charCount;
            Char *chars;
        };

        BMFont(Graphics *graphics, const C8 *descriptionFile);
        virtual ~BMFont();

        // From Font:

        virtual bool init();
        virtual bool reload();

        virtual void setCharacterSpacing(I32 spacing) { mSpacing = spacing; }
        virtual I32 getCharacterSpacing() { return mSpacing; }
        virtual I32 getFontHeight();
        virtual REAL getFontHeight(REAL scale);
        virtual bool hasCharacter(UI32 character);
        virtual REAL getStringWidth(const C8 *string, REAL scale, UI32 substrLength = 0);

        virtual REAL drawString(REAL x, REAL y, const C8 *string,
                                UI32 flags = IF_ALIGN_TOP_LEFT, REAL scale = 1,
                                const Color &color = Color(0xffffffff), UI32 substrLength = 0);

        // Local:

        const C8 * getFontName() const;

    private:

        I32 findChar(UI32 ch);
        I32 findKern(I32 first, I32 second);
        I32 findKern(I32 first, I32 second, I32 firstCharIndex);

        I32 mSpacing;
        Graphics *mGraphics;
        C8 mFileName[MAX_FILENAME_LENGTH];
        FontData mFontData;

    }; // class BMFont

} // namespace turska


#endif // !T2BMFONT_H_INCLUDED
